package com.example.foo.api.web.passport;

import java.time.Duration;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.ad.api.utils.SmsSendUtils;
import com.ruoyi.common.core.domain.AjaxResult;
import com.example.foo.api.boot.TokenHelper;
import com.example.foo.ftt.FttUserException;
import com.example.foo.ftt.model.FttUser;
import com.example.foo.ftt.service.FttUserFacadeService;
import com.example.foo.ftt.service.FttUserService;
import com.example.foo.p.service.FttRegisterService;
import com.example.support.redis.RedisHelper;
import com.example.util.RegexSnippetUtils;

@org.springframework.web.bind.annotation.RestController
public class UserAccesstokenAction {

	private final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(getClass());

	private final FttUserService fttUserService;
	private final FttUserFacadeService fttUserFacadeService;
	private final FttRegisterService fttRegisterService;

	public UserAccesstokenAction(FttUserService fttUserService,
			FttUserFacadeService fttUserFacadeService,
			FttRegisterService fttRegisterService) {
		this.fttUserService = fttUserService;
		this.fttUserFacadeService = fttUserFacadeService;
		this.fttRegisterService = fttRegisterService;
	}

	@PostMapping(path = "/passport/accesstokens", params = "grantType=ftt")
	public AjaxResult createUserAccesstokenByFtt(HttpServletRequest request,
			@RequestParam("cellphone") String cellphone,
			@RequestParam("verificationCode") String verificationCode,
			@RequestParam(value = "referralCode", required = false) String referralCode) {
		//
		if (StringUtils.isBlank(cellphone)) {
			return AjaxResult.error(400, "cellphone must not be null");
		}
		if (StringUtils.isBlank(verificationCode)) {
			return AjaxResult.error(400, "verificationCode must not be null");
		}
		if (!RegexSnippetUtils.isCellphone_CN(cellphone)) {
			return AjaxResult.error(400, "手机号格式错误");
		}

		//
		if (!SmsSendUtils.verfySmsCode(cellphone, verificationCode)) {
			return AjaxResult.error(400, "验证码错误");
		}

		//
		Long userId;

		//
		String lockKey = String.format("lock:register:cellphone_%s", cellphone);
		if (!RedisHelper.setnxex(lockKey, 10, "-")) {
			return AjaxResult.error(400, "操作频繁，请稍后");
		}
		try {
			FttUser fttUser = fttUserService.findFttUserByCellphone(cellphone);
			if (fttUser == null && StringUtils.isBlank(referralCode)) {
				return AjaxResult.error(400, "referralCode must not be null");
			}
			if (fttUser != null && StringUtils.isNotBlank(referralCode)) {
				return AjaxResult.error(400, "手机号已注册");
			}
			if (fttUser != null && fttUser.getState() == FttUser.State.banned) {
				return AjaxResult.error(400, "账号异常");
			}

			if (fttUser == null) {
				FttUser referralParentFttUser = fttUserService.findFttUserByReferralCode(referralCode);
				if (referralParentFttUser == null) {
					return AjaxResult.error(400, "邀请码不存在");
				}
				if (referralParentFttUser.getState() != FttUser.State.normal) {
					throw new FttUserException(String.format("该邀请码%s已禁止使用", referralCode));
				}

				fttUser = fttRegisterService.createFttUserRegisterByCellphone(cellphone, referralParentFttUser);

				try {
					Long parentUserId = referralParentFttUser.getUserId();
					fttUserFacadeService.updateFttUserParents(fttUser.getId(), parentUserId);
				} catch (FttUserException e) {
					log.warn(e.getMessage());
				} catch (Exception e) {
					log.warn(e.getMessage(), e);
				}
			}

			userId = fttUser.getUserId();
		} finally {
			//lock.unlock();
		}

		//
		Duration expiresIn = Duration.ofDays(15);
		String accesstoken = TokenHelper.createToken(userId, expiresIn);

		UserAccesstoken userAccesstoken = new UserAccesstoken(userId, accesstoken, (int) expiresIn.getSeconds());
		return AjaxResult.successData(userAccesstoken);
	}

}
